package com.jomoo.css.common.core.dao.impl;

import com.jomoo.css.common.core.model.BaseEntity;
import com.jomoo.css.common.core.util.AssertHelper;
import com.jomoo.css.common.core.util.DateUtils;
import com.jomoo.css.common.core.vo.SysUserVO;
import com.jomoo.css.common.core.constant.CommonConstants;
import com.jomoo.css.common.core.context.ContextHolder;
import com.jomoo.css.common.core.dao.EntityOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Date;

@Slf4j
@Component
public class SecurityEntityOperation implements EntityOperation {

	private static final String DEFAULT_PROCESS_MAN = "SYSTEM";

	@Autowired()
	BaseDaoSimple baseDao;

	@Override
	public Boolean beforeSave(Object arg) {
		if (arg instanceof BaseEntity) {
			BaseEntity baseEntity = (BaseEntity) arg;
			if (AssertHelper.empty(baseEntity.getId())) {
				proceeSaveArg(arg);
			} else {
				proceeUpdateArg(arg);
			}
		}
		return true;
	}

	@Override
	public void afterSave(Object o) {

	}

	@Override
	public Boolean beforeUpdate(Object arg) {
		proceeUpdateArg(arg);
		return true;
	}

	@Override
	public void afterUpdate(Object o) {

	}

	@Override
	public Boolean beforeDelete(Object arg) {
		if (arg instanceof BaseEntity) {
			BaseEntity baseEntity = (BaseEntity) arg;
			if (baseEntity != null) {
				baseEntity = (BaseEntity) baseDao.get(baseEntity.getClass(), baseEntity.getId());
				proceeRemoveArg(baseEntity);
			}
		}
		return true;
	}

	@Override
	public void afterDelete(Object arg) {

	}

	private void proceeUpdateArg(Object arg) {
		if (arg instanceof BaseEntity) {
			BaseEntity baseEntity = (BaseEntity) arg;
			if (baseEntity != null) {
				processBaseEntity(baseEntity);
				SysUserVO currentUser = ContextHolder.getCurrentUser();
				if (currentUser != null) {
					String staffNo = currentUser == null ? "-1" : currentUser.getStaffNo();
					baseEntity.setModifiedBy(staffNo);
					baseEntity.setModifiedByName(currentUser.getCname());
					baseEntity.setModifiedByEnName(currentUser.getEname());
				}
				baseEntity.setModifiedDate(new Date());
				//导致versionId失效所以注释了
//                baseEntity.setVersionId(baseEntity.getVersionId() == null ? 1 : baseEntity.getVersionId() + 1);
				if (baseEntity.getArchiveBaseDate() == null) {
					baseEntity.setArchiveBaseDate(DateUtils.addYear(new Date(), 2));
				}
				if (baseEntity.getDelFlag() == null) {
					baseEntity.setDelFlag(CommonConstants.STATUS_NORMAL);
				}
			}
		} else if (arg instanceof Collection) {
			for (Object entity : (Collection) arg) {
				proceeUpdateArg(entity);
			}
		}
	}

	private void proceeSaveArg(Object arg) {
		if (arg instanceof BaseEntity) {
			BaseEntity baseEntity = (BaseEntity) arg;
			if (baseEntity != null) {
				processBaseEntity(baseEntity);
//                if (baseEntity.getVersionId() == null) {
//                    baseEntity.setVersionId(1);
//                }
				if (baseEntity.getDelFlag() == null) {
					baseEntity.setDelFlag(CommonConstants.STATUS_NORMAL);
				}
				SysUserVO currentUser = ContextHolder.getCurrentUser();
				//String userName = currentUser == null ? "SYSTM" : currentUser.getUserName();
				String cname = currentUser == null ? DEFAULT_PROCESS_MAN : currentUser.getCname();
				String eName = currentUser == null ? DEFAULT_PROCESS_MAN : currentUser.getEname();
				String staffNo = currentUser == null ? "-1" : currentUser.getStaffNo();
				staffNo = staffNo == null ? currentUser.getUserName() : staffNo;
				if (baseEntity.getCreateDate() == null) {
					baseEntity.setCreateDate(new Date());
				}
				if (baseEntity.getCreatedBy() == null) {
					baseEntity.setCreatedBy(staffNo);
				}
				if (baseEntity.getCreatedByName() == null) {
					baseEntity.setCreatedByName(cname);
				}
				if (baseEntity.getCreatedByEnName() == null) {
					baseEntity.setCreatedByEnName(eName);
				}
				if (baseEntity.getModifiedBy() == null) {
					baseEntity.setModifiedBy(staffNo);
				}
				if (baseEntity.getModifiedByName() == null) {
					baseEntity.setModifiedByName(cname);
				}
				if (baseEntity.getModifiedByEnName() == null) {
					baseEntity.setModifiedByEnName(eName);
				}
				if (baseEntity.getModifiedDate() == null) {
					baseEntity.setModifiedDate(new Date());
				}
				if (baseEntity.getArchiveBaseDate() == null) {
					baseEntity.setArchiveBaseDate(DateUtils.addYear(new Date(), 2));
				}
				baseEntity.setTenantId(ContextHolder.getTenantId());
				log.info("tenantId:" + baseEntity.getTenantId());
			}
		} else if (arg instanceof Collection) {
			for (Object entity : (Collection) arg) {
				proceeSaveArg(entity);
			}
		}
	}

	private void proceeRemoveArg(Object arg) {
		if (arg instanceof BaseEntity) {
			BaseEntity baseEntity = (BaseEntity) arg;
			if (baseEntity != null) {
				processBaseEntity(baseEntity);
				SysUserVO currentUser = ContextHolder.getCurrentUser();
				String staffNo = currentUser == null ? "-1" : currentUser.getStaffNo();
				baseEntity.setDeleteBy(staffNo);
				baseEntity.setDeleteDate(new Date());
				baseEntity.setDelFlag(CommonConstants.STATUS_DEL);
				if (baseEntity.getArchiveBaseDate() == null) {
					baseEntity.setArchiveBaseDate(DateUtils.addYear(new Date(), 2));
				}
			}
		} else if (arg instanceof Collection) {
			for (Object entity : (Collection) arg) {
				proceeRemoveArg(entity);
			}
		}
	}

	private void processBaseEntity(BaseEntity baseEntity) {
//        if (baseEntity.getBizOrgCode() == null) {
//            baseEntity.setBizOrgCode(ContextUtils.getOperationOrgCode());
//        }
//        if (baseEntity.getCompanyId() == null) {
//            baseEntity.setCompanyId(ContextUtils.getFixedCompanyId());
//        }
		if (baseEntity.getCreateDate() == null) {
			baseEntity.setCreateDate(new Date());
		}
		SysUserVO currentUser = ContextHolder.getCurrentUser();
		String staffNo = currentUser == null ? "-1" : currentUser.getStaffNo();
		staffNo = staffNo == null ? currentUser.getUserName() : staffNo;
		String name = currentUser == null ? DEFAULT_PROCESS_MAN : currentUser.getCname();
		String enName = currentUser == null ? DEFAULT_PROCESS_MAN : currentUser.getEname();
		if (baseEntity.getCreatedBy() == null) {
			baseEntity.setCreatedBy(staffNo);
		}
		if (baseEntity.getCreatedByName() == null) {
			baseEntity.setCreatedByName(name);
		}
		if (baseEntity.getCreatedByEnName() == null) {
			baseEntity.setCreatedByEnName(enName);
		}
//        if (baseEntity.getDataowner() == null) {
//            baseEntity.setDataowner(ContextUtils.getDataOwner());
//        }
	}
}
